package com.pedro.streamer;


import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.view.Surface;

import androidx.annotation.Nullable;


import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.ext.rtmp.RtmpDataSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.pedro.streamer.exo.CustomRenderersFactory;


public class RtmpPlayer {

    private static final String TAG = "YGPlayer";
    Context context;
    SimpleExoPlayer player;
    Handler handler;
//    boolean canSeek = true;

    public RtmpPlayer(Context context,boolean useCamea1) {
        HandlerThread handlerThread = new HandlerThread("ExoPlayerThread");
        handlerThread.start();
        handler = new Handler(handlerThread.getLooper());

        this.context = context;
        AdaptiveTrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory();
        DefaultTrackSelector trackSelector = new DefaultTrackSelector(/* context= */ context, trackSelectionFactory);

        handler.post(() -> {
            if (useCamea1){
                player = new SimpleExoPlayer.Builder(/* context= */ context, new CustomRenderersFactory(context))
                        .setTrackSelector(trackSelector)
                        .build();
            }else{
                player = new SimpleExoPlayer.Builder(/* context= */ context)
                        .setTrackSelector(trackSelector)
                        .build();
            }


        });



    }


    public void setDataSource(String videoUrl1) {
        handler.post(() -> {
            String videoUrl = "rtmp://127.0.0.1:1935/file/live";
//            String videoUrl = videoUrl1;
            Uri url = Uri.parse(videoUrl);
            MediaSource videoSource;
            if ("rtmp".equals(videoUrl.substring(0, 4))) {
                RtmpDataSource.Factory dataSourceFactory = new RtmpDataSource.Factory();
                videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(url);
            } else {
                videoSource = new ProgressiveMediaSource.Factory(
                        new DefaultDataSourceFactory(context, "ExoPlayer"))
                        .createMediaSource(url);

            }

            player.addListener(new ExoPlayer.Listener() {
                @Override
                public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
//                    if (playbackState == ExoPlayer.STATE_READY &&canSeek) {
//                        if (!"http".equals(videoUrl.substring(0, 4))) {
//                            canSeek = false;
//                            long duration = player.getContentDuration();
//                            long nowTime = System.currentTimeMillis();
//                            long timeStart = 1672502400000L;
//                            long seekTime = (nowTime - timeStart) % duration;
//                            seekTo(seekTime);
//                            Log.e(TAG, "player is ready ,seek action duration="+duration+", seektime="+ seekTime);
//                        }
//                    }
                }
                @Override
                public void onPlaybackStateChanged(int playbackState) {
                    Player.Listener.super.onPlaybackStateChanged(playbackState);
                    if (playbackState == Player.STATE_ENDED) {
                        seekTo(0);
                        start();
                        Log.e(TAG, "player is end seek 0 and start play");
                    }

                }

                @Override
                public void onPlayerErrorChanged(@Nullable PlaybackException error) {
                    Player.Listener.super.onPlayerErrorChanged(error);
                    if(error!=null){
                        Log.e(TAG, "player onPlayerErrorChanged errCodeName="+error.getErrorCodeName()+" code="+error.errorCode+" msg="+error.getLocalizedMessage());
                    }
                }

                @Override
                public void onPlayerError( PlaybackException error) {
                    Player.Listener.super.onPlayerError(error);
                    if(error!=null){
                        Log.e(TAG, "player onPlayerError errCodeName="+error.getErrorCodeName()+" code="+error.errorCode+" msg="+error.getLocalizedMessage());
                    }
                }

                @Override
                public void onIsLoadingChanged(boolean isLoading) {
                    Player.Listener.super.onIsLoadingChanged(isLoading);
                    Log.e(TAG, "player onIsLoadingChanged="+isLoading);
                }
            });

            player.setRepeatMode(Player.REPEAT_MODE_ONE);
            player.prepare(videoSource);

        });

    }

    public void seekTo(long time) {
        Log.e(TAG, "player seekTo");
        handler.post(() -> {
            player.seekTo(time);
        });
    }
    public void start() {
        Log.e(TAG, "player start");
        handler.post(() -> {
            player.play();
        });
    }

    public void prepare() {
        Log.e(TAG, "player prepare");
    }

    public void stop() {
        Log.e(TAG, "player stop");
        handler.post(() -> {
            player.stop();
        });

    }

    public void reset() {

    }

    public void release() {
        Log.e(TAG, "player release");

        handler.post(() -> {
            player.release();
        });
    }

    public void setSurface(Surface surface) {
        Log.e(TAG, "player setSurface"+surface);
        handler.post(() -> {
            if (player != null) {
                player.setVideoSurface(surface);
            }
        });
    }

    public void setVolume(float left, float right) {
        handler.post(() -> {
            player.setVolume(left);
        });
    }

    public void setLooping(boolean loop) {

    }


}
